package jm.nj.demo15mian.demo03;

import java.lang.reflect.Method;

/*
* 通过反射技术获取类中的方法并执行
* 1.获取class文件对象
* 2.通过Class对象中提供的方法获取类成员中的成员方法
* 3.通过Method 中提供的 方法,执行成员方法
*
* public String getId()
 * public void setId(String id)
 * private void method()
* */
public class Demo05Reflect {
    public static void main(String[] args) throws Exception {
        //获取class文件对象
        Class clazz = Class.forName("jm.nj.demo15mian.demo02.Person");
        //2.通过Class对象中提供的方法获取类中的成员方法
        /*
        * Method[] getMethod() 获取类中和父类/父接口中继承的方法
        * Method[] getDeclaredMethods()  包括公共,保护,默认(包)访问的私有方法,但不包括私有的方法
        *
        * */
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

        System.out.println("===============");

        Method[] mds = clazz.getDeclaredMethods();
        for (Method md : mds) {
            System.out.println(md);
        }
        System.out.println("=======");
        /*
        * Method getMethod(String name, Class<?>... parameterTypes)  获取指定公共成员方法。
        * Method getDeclaredMethod(String name, class<?>...parametTypes)
        *
        * 参数:
        * name :方法的字符串格式名称
        * parametTypes:方法参数class文件对象
        * */
        //public String getId()
        Method getIdMethod = clazz.getMethod("getId");
        System.out.println(getIdMethod);

        //private void method()
        Method method = clazz.getDeclaredMethod("method");
        System.out.println(method);

        //public void setId(String id)
        Method setId = clazz.getMethod("setId", String.class);
        System.out.println(setId);

        //3.通过Method中的提供的方法,执行成员方法
        /*
         * Object invoke(Object obj, Object... args)  对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。
         * 返回值:
         * 	Object:方法有返回值,就返回对应的值;方法没有返回值返回null
         * 参数:
         * 	obj:被反射的对象(Perosn),你要执行的方法是哪个对象中的
         * 	args:调用方法时要传递的实际参数
         */

        Object obj = clazz.newInstance();
        //执行getId
        Object v1 = getIdMethod.invoke(obj);
        System.out.println(v1);

        //执行setId 方法
        Object v2 = setId.invoke(obj,"007");
        System.out.println(v2);

        //赋值重新获取变量的值
        v1= getIdMethod.invoke(obj);
        System.out.println(v1);

        method.setAccessible(true);
        method.invoke(obj);


    }
}
